using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace AreaBuilder.Forms {
    public partial class frmAreaSettings : Form {
        private readonly AreaHolder ah;
        private int lastVnum;
        private int origVnum;

        public frmAreaSettings() {
            InitializeComponent();
        }

        public frmAreaSettings(AreaHolder ah) {
            InitializeComponent();

            this.ah = ah;
        }

        private void frmAreaSettings_Load(object sender, EventArgs e) {
            txtFilename.Text = ah.area.File;
            txtName.Text = ah.area.Title;
            txtAuthor.Text = ah.area.Author;
            txtMinVnum.Text = ah.area.MinVnum.ToString();
            txtMaxVnum.Text = ah.area.MaxVnum.ToString();
            txtMinLevel.Text = ah.area.MinLevel.ToString();
            txtMaxLevel.Text = ah.area.MaxLevel.ToString();

            origVnum = ah.area.MinVnum;
            lastVnum = ah.area.MaxVnum;
        }

        private void btnCancel_Click(object sender, EventArgs e) {
            Dispose();
        }

        private void btnOK_Click(object sender, EventArgs e) {
            ah.area.File = txtFilename.Text;
            ah.area.Title = txtName.Text;
            ah.area.Author = txtAuthor.Text;
            ah.area.MinVnum = Int32.Parse(txtMinVnum.Text);
            ah.area.MaxVnum = Int32.Parse(txtMaxVnum.Text);
            ah.area.MinLevel = Int32.Parse(txtMinLevel.Text);
            ah.area.MaxLevel = Int32.Parse(txtMaxLevel.Text);

            MdiParent.Text = String.Format("The Burning Eye :: Area Builder [{0}]", txtName.Text);

            int newVnumDelta = origVnum - ah.area.MinVnum;

            if (newVnumDelta != 0)
                renumberArea(newVnumDelta);

            Dispose();
        }

        private void renumberArea(int delta) {
            foreach (Mobile mob in ah.area.Mobs) {
                if (isInRange(mob.VNum)) {
                    mob.VNum -= delta;

                    foreach (MobProgLink mpl in mob.Progs)
                        mpl.Program -= delta;
                }
            }

            foreach (Room room in ah.area.Rooms) {
                if (isInRange(room.VNum)) {
                    room.VNum -= delta;

                    foreach (RoomExit re in room.Exits) {
                        if (isInRange(re.LinkVNum)) {
                            re.LinkVNum -= delta;

                            if (re.KeyVNum > 0 && isInRange(re.KeyVNum))
                                re.KeyVNum -= delta;
                        }
                    }
                }
            }

            foreach (Item item in ah.area.Items) {
                if (isInRange(item.VNum)) {
                    item.VNum -= delta;

                    foreach (ItemTrigger it in item.Triggers) {
                        String[] words = Regex.Split(it.TriggerSpell, @"\s");

                        foreach (String w in words) {
                            int foundVNum;

                            if (Int32.TryParse(w, out foundVNum) && isInRange(foundVNum) && it.TriggerSpell.Contains(foundVNum.ToString())) {
                                DialogResult dr =
                                    MessageBox.Show(
                                        String.Format(
                                            "Possible VNum match found in object #{0} objprog: {1}. Should I update it to {2}?{3}{3}{4}", item.VNum, foundVNum, foundVNum - delta, Environment.NewLine, it.TriggerSpell),
                                        "Input needed", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                                if (dr == DialogResult.Yes) {
                                    it.TriggerSpell = Regex.Replace(it.TriggerSpell, foundVNum.ToString(), 
                                                                    (foundVNum - delta).ToString());
                                }
                            }
                        }
                    }
                }
            }

            foreach (Shop shop in ah.area.Shops)
                if (isInRange(shop.VNum))
                    shop.VNum -= delta;

            foreach (MobProg mp in ah.area.Progs) {
                if (isInRange(mp.VNum)) {
                    mp.VNum -= delta;
                    
                    String[] words = Regex.Split(mp.Program, @"\s");

                    foreach (String w in words) {
                        int foundVNum;

                        if (Int32.TryParse(w, out foundVNum) && isInRange(foundVNum) && mp.Program.Contains(foundVNum.ToString())) {
                            DialogResult dr =
                                MessageBox.Show(
                                    String.Format(
                                        "Possible VNum match found in mobprog #{0}: {1}. Should I update it to {2}?{3}{3}{4}", mp.VNum, foundVNum, foundVNum - delta, Environment.NewLine, mp.Program),
                                    "Input needed", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                            if (dr == DialogResult.Yes) {
                                mp.Program = Regex.Replace(mp.Program, foundVNum.ToString(),
                                                           (foundVNum - delta).ToString());
                            }
                        }
                    }
                }
            }

            foreach (Reset reset in ah.area.Resets) {
                // M    0       <mobile vnum>   <area limit>                <room vnum>             <room limit>
                // O    0       <object vnum>   <global limit>              <room vnum>
                // P    0       <object vnum>   <global limit>              <container vnum>        <# of copies>
                // G    0       <object vnum>   <global limit>              <wear location (-1)>
                // E    0       <object vnum>   <global limit>              <wear flag #>
                // D    0       <room vnum>     <exit direction>            <door condition>
                // R    0       <room vnum>     <# of exits to randomize>
                // type slot    vnum            limit                       roomVnum                roomLimit
                // @"(?<type>[M|O|P|G|E|D|R|S])\s+(?<slot>\d)\s+(?<vnum>\d+)\s+(?<limit>\-?\d+)(\s+(?<roomvnum>\-?\d+)\s+(?<roomlimit>\-?\d+)|\s+(?<roomvnum>\-?\d*)|\s*)\s*[^\0]*\0",
                // Type = m.Groups["type"].Value,
                // Slot = Int32.Parse(m.Groups["slot"].Value),
                // VNum = Int32.Parse(m.Groups["vnum"].Value),
                // Limit = Int32.Parse(m.Groups["limit"].Value),
                // VNumWear = m.Groups["roomvnum"].Value,
                // ExtraParam = m.Groups["roomlimit"].Value

                if (!isInRange(reset.VNum))
                    continue;

                reset.VNum -= delta;

                switch (reset.Type) {
                    case "M":
                    case "O":
                    case "P":
                        reset.VNumWear = (Int32.Parse(reset.VNumWear) - delta).ToString();

                        break;

                    default:
                        break;
                }
            }

            foreach (Special special in ah.area.Specials)
                if (isInRange(special.VNum))
                    special.VNum = special.VNum - delta;
        }

        private bool isInRange(int vnum) {
            return ((vnum >= origVnum) && (vnum <= lastVnum));
        }

        private void txtFilename_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);
        }

        private void txtName_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);
        }

        private void txtAuthor_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);
        }

        private void txtMinVnum_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);

            if (!Char.IsDigit(e.KeyChar))
                return;
        }

        private void txtMaxVnum_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);

            if (!Char.IsDigit(e.KeyChar))
                return;
        }

        private void txtMaxLevel_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);

            if (!Char.IsDigit(e.KeyChar))
                return;
        }

        private void txtMinLevel_KeyPress(object sender, KeyPressEventArgs e) {
            if (e.KeyChar == 13)
                btnOK_Click(null, null);

            if (!Char.IsDigit(e.KeyChar))
                return;
        }
    }
}